/**
 * 打字管理器
 * 负责处理用户输入和计算打字速度
 */
class TypingManager {
    constructor(game) {
        // 游戏实例引用
        this.game = game;
        
        // 当前文本
        this.text = '';
        
        // 当前位置
        this.position = 0;
        
        // 输入历史
        this.inputHistory = [];
        
        // 错误计数
        this.errors = 0;
        
        // 连续正确输入计数
        this.consecutiveCorrect = 0;
        
        // 最近60秒的输入记录（用于计算WPM）
        this.recentInputs = [];
        
        // 文本库
        this.textLibrary = {
            easy: [
                "小偷悄悄溜进了商店，他环顾四周确保没人注意到他。",
                "警察巡逻的脚步声越来越近，小偷加快了脚步。",
                "这是一次完美的逃脱，没有人能追上这个敏捷的小偷。"
            ],
            medium: [
                "小偷轻手轻脚地穿过走廊，每一步都小心翼翼，生怕发出任何声响。保安就在隔壁房间，稍有不慎就会被发现。",
                "警察局长发誓要抓住这个臭名昭著的珠宝大盗，他调集了城市里最优秀的警员组成特别行动小组。",
                "这次的目标是市中心博物馆的镇馆之宝——一颗据说有魔力的蓝宝石，传说它能给持有者带来无尽的财富。"
            ],
            hard: [
                "这位臭名昭著的国际大盗以其精湛的技艺和不可思议的逃脱能力而闻名于世，他曾在多个国家的高度戒备的博物馆和银行之间来去自如，每次都能神不知鬼不觉地带走价值连城的宝物，让各国警方束手无策。",
                "警方这次部署了最先进的安保系统，包括红外线探测器、压力感应地板、热成像摄像头以及生物识别门禁，他们坚信这次万无一失，没有任何小偷能够突破这样严密的防御网络。",
                "小偷站在摩天大楼的楼顶，俯瞰着城市的灯火辉煌，他知道自己即将面临职业生涯中最具挑战性的一次行动，但他的嘴角却勾起一丝自信的微笑，因为挑战越大，成功后的满足感就越强烈。"
            ]
        };
    }
    
    /**
     * 加载文本
     * @param {string} difficulty 难度
     */
    loadText(difficulty) {
        // 重置状态
        this.reset();
        
        // 确定文本路径
        const textPath = `assets/texts/${difficulty}/`;
        
        // 随机选择一个文本文件
        const textFiles = ['text1.txt', 'text2.txt', 'text3.txt'];
        const randomFile = textFiles[Math.floor(Math.random() * textFiles.length)];
        
        // 加载文本文件
        fetch(`${textPath}${randomFile}`)
            .then(response => {
                if (!response.ok) {
                    throw new Error(`无法加载文本文件: ${response.status}`);
                }
                return response.text();
            })
            .then(text => {
                // 设置文本
                this.setText(text.trim());
                console.log(`已加载${difficulty}难度文本`);
            })
            .catch(error => {
                console.error('加载文本失败:', error);
                // 使用备用文本
                this.useBackupText(difficulty);
            });
    }
    
    /**
     * 使用备用文本（当文件加载失败时）
     * @param {string} difficulty 难度
     */
    useBackupText(difficulty) {
        // 备用文本库（英文）
        const backupTexts = {
            easy: [
                "The thief sneaked into the store, looking around to make sure no one noticed him.",
                "The sound of police patrol footsteps was getting closer, and the thief quickened his pace.",
                "This was a perfect escape, no one could catch up with this agile thief."
            ],
            medium: [
                "The thief tiptoed through the hallway, each step careful, afraid to make any noise. The security guard was in the next room, and any mistake would lead to discovery.",
                "The police chief vowed to catch the notorious jewel thief, gathering the city's best officers to form a special task force.",
                "The target this time was the centerpiece of the downtown museum - a sapphire said to have magical powers, rumored to bring endless wealth to its owner."
            ],
            hard: [
                "This infamous international thief was known for his exquisite skills and incredible escape abilities. He moved freely between highly guarded museums and banks in multiple countries, each time mysteriously taking away priceless treasures, leaving various police forces helpless.",
                "The police deployed the most advanced security system this time, including infrared detectors, pressure-sensitive floors, thermal imaging cameras, and biometric access control. They were confident that this time it was foolproof, and no thief could break through such a tight defense network.",
                "The thief stood on the rooftop of the skyscraper, overlooking the brilliant lights of the city. He knew he was about to face the most challenging operation of his career, but a confident smile curled at the corners of his mouth, because the greater the challenge, the stronger the satisfaction after success."
            ]
        };
        
        // 随机选择一个备用文本
        const texts = backupTexts[difficulty] || backupTexts.medium;
        const randomText = texts[Math.floor(Math.random() * texts.length)];
        
        // 设置文本
        this.text = randomText;
        this.displayText();
        console.log(`使用备用${difficulty}难度文本`);
    }
    
    /**
     * 显示文本
     */
    displayText() {
        const textDisplay = document.getElementById('text-display');
        
        // 清空文本显示区域
        textDisplay.innerHTML = '';
        
        // 已打部分
        if (this.position > 0) {
            const typedSpan = document.createElement('span');
            typedSpan.className = 'typed';
            typedSpan.textContent = this.text.substring(0, this.position);
            textDisplay.appendChild(typedSpan);
        }
        
        // 当前字符
        if (this.position < this.text.length) {
            const currentSpan = document.createElement('span');
            currentSpan.className = 'current';
            currentSpan.textContent = this.text[this.position];
            textDisplay.appendChild(currentSpan);
            
            // 更新光标位置
            const cursor = document.getElementById('cursor');
            const currentChar = textDisplay.querySelector('.current');
            if (currentChar) {
                const rect = currentChar.getBoundingClientRect();
                const parentRect = textDisplay.getBoundingClientRect();
                cursor.style.left = `${rect.left - parentRect.left}px`;
                cursor.style.top = `${rect.top - parentRect.top}px`;
            }
        }
        
        // 未打部分
        if (this.position < this.text.length - 1) {
            const remainingSpan = document.createElement('span');
            remainingSpan.textContent = this.text.substring(this.position + 1);
            textDisplay.appendChild(remainingSpan);
        }
    }
    
    /**
     * 初始化打字管理器
     */
    init() {
        // 重置状态
        this.reset();
        
        // 移除之前的键盘事件监听器（如果有）
        document.removeEventListener('keydown', this.boundHandleKeyDown);
        
        // 绑定方法并保存引用
        this.boundHandleKeyDown = this.handleKeyDown.bind(this);
        
        // 添加键盘事件监听
        document.addEventListener('keydown', this.boundHandleKeyDown);
        
        console.log('打字管理器初始化完成');
    }
    
    /**
     * 处理键盘按下事件
     * @param {KeyboardEvent} event 键盘事件
     */
    handleKeyDown(event) {
        console.log('键盘事件触发:', event.key);
        console.log('游戏状态:', this.game.isRunning, this.game.isPaused);
        
        // 如果游戏暂停或未运行，不处理输入
        if (!this.game.isRunning || this.game.isPaused) {
            console.log('游戏未运行或已暂停');
            return;
        }
        
        // 如果已经完成文本，不处理输入
        if (this.isCompleted()) {
            console.log('文本已完成');
            return;
        }
        
        // 获取按键
        const key = event.key;
        
        // 如果是空格键且有道具，使用道具
        if (key === ' ' && this.game.itemManager.hasItem()) {
            // 阻止默认行为（滚动页面）
            event.preventDefault();
            
            // 如果当前字符也是空格，则同时处理输入和使用道具
            if (this.text[this.position] === ' ') {
                this.processInput(key);
            }
            
            // 使用道具
            this.game.itemManager.useItem();
            return;
        }
        
        // 如果是功能键、修饰键等，不处理
        if (key.length > 1 && !['Backspace', 'Enter'].includes(key)) {
            return;
        }
        
        // 阻止默认行为（避免页面滚动等）
        event.preventDefault();
        
        // 处理输入
        console.log('处理输入:', key);
        this.processInput(key);
    }
    
    /**
     * 处理输入
     * @param {string} key 输入的键
     */
    processInput(key) {
        // 如果游戏未运行或已完成，不处理输入
        if (!this.game.isRunning || this.isCompleted()) {
            return;
        }
        
        // 获取当前字符
        const currentChar = this.text.charAt(this.position);
        
        // 检查输入是否正确
        const isCorrect = key === currentChar;
        
        // 记录输入历史
        this.inputHistory.push({
            key: key,
            expected: currentChar,
            isCorrect: isCorrect,
            timestamp: Date.now()
        });
        
        // 记录最近60秒的输入
        this.recordRecentInput(isCorrect);
        
        // 如果输入正确
        if (isCorrect) {
            // 增加连续正确计数
            this.consecutiveCorrect++;
            
            // 播放正确音效
            this.game.audioManager.playSound('correct');
            
            // 显示按键效果
            this.showKeyPressEffect(key, true);
            
            // 移动到下一个字符
            this.position++;
            
            // 更新文本显示
            this.displayText();
        } else {
            // 重置连续正确计数
            this.consecutiveCorrect = 0;
            
            // 增加错误计数
            this.errors++;
            
            // 播放错误音效
            this.game.audioManager.playSound('error');
            
            // 显示按键效果
            this.showKeyPressEffect(key, false);
            
            // 让小偷踉跄
            this.game.characterManager.stumble();
        }
        
        // 检查是否完成
        if (this.isCompleted()) {
            console.log('文本输入完成');
        }
    }
    
    /**
     * 记录最近输入
     * @param {boolean} isCorrect 是否正确
     */
    recordRecentInput(isCorrect) {
        const now = Date.now();
        
        // 添加新输入
        this.recentInputs.push({
            timestamp: now,
            isCorrect: isCorrect
        });
        
        // 移除超过60秒的输入
        const cutoffTime = now - 60000;
        this.recentInputs = this.recentInputs.filter(input => input.timestamp >= cutoffTime);
    }
    
    /**
     * 计算打字速度(WPM)
     * @returns {number} 打字速度(WPM)
     */
    calculateWPM() {
        // 如果没有输入，返回0
        if (this.inputHistory.length === 0) {
            return 0;
        }
        
        // 计算经过的时间（分钟）
        const elapsedMinutes = this.game.gameData.elapsedTime / 60;
        if (elapsedMinutes === 0) return 0;
        
        // 计算最近30秒内的正确输入数
        const now = Date.now();
        const recentTime = 30 * 1000; // 30秒
        const recentInputs = this.inputHistory.filter(input => 
            input.isCorrect && (now - input.timestamp) <= recentTime
        );
        
        // 计算最近30秒的时间窗口（分钟）
        const recentTimeMinutes = Math.min(elapsedMinutes, recentTime / 60000);
        
        // 如果时间窗口太小，使用整体平均
        if (recentTimeMinutes < 0.1) {
            const totalCorrect = this.inputHistory.filter(input => input.isCorrect).length;
            return (totalCorrect / elapsedMinutes) / 5;
        }
        
        // 计算最近时间窗口内的WPM
        const recentCorrect = recentInputs.length;
        const wpm = (recentCorrect / recentTimeMinutes) / 5;
        
        console.log(`WPM计算: 时间=${recentTimeMinutes.toFixed(2)}分钟, 正确字符=${recentCorrect}, WPM=${wpm.toFixed(1)}`);
        
        return wpm;
    }
    
    /**
     * 计算正确率
     * @returns {number} 正确率百分比
     */
    calculateAccuracy() {
        // 如果没有输入，返回100%
        if (this.inputHistory.length === 0) {
            return 100;
        }
        
        // 计算正确输入的数量
        const correctCount = this.inputHistory.filter(input => input.isCorrect).length;
        
        // 计算正确率
        const accuracy = (correctCount / this.inputHistory.length) * 100;
        
        return accuracy;
    }
    
    /**
     * 获取连续正确输入数
     * @returns {number} 连续正确输入数
     */
    getConsecutiveCorrect() {
        return this.consecutiveCorrect;
    }
    
    /**
     * 检查是否完成文本
     * @returns {boolean} 是否完成
     */
    isCompleted() {
        // 只有当文本非空且位置达到文本末尾时才返回true
        const completed = this.text.length > 0 && this.position >= this.text.length;
        if (completed) {
            console.log('文本输入完成！位置:', this.position, '文本长度:', this.text.length);
        }
        return completed;
    }
    
    /**
     * 重置状态
     */
    reset() {
        this.position = 0;
        this.inputHistory = [];
        this.errors = 0;
        this.consecutiveCorrect = 0;
        this.recentInputs = [];
    }
    
    /**
     * 设置文本
     * @param {string} text 要设置的文本
     */
    setText(text) {
        this.text = text;
        
        // 重置状态
        this.reset();
        
        // 显示文本
        this.displayText();
        
        console.log('文本已设置，长度:', text.length);
    }
    
    /**
     * 显示按键按下效果
     * @param {string} key 按键
     * @param {boolean} isCorrect 是否正确
     */
    showKeyPressEffect(key, isCorrect) {
        // 创建按键效果元素
        const keyEffect = document.createElement('div');
        keyEffect.className = `key-effect ${isCorrect ? 'correct' : 'incorrect'}`;
        keyEffect.textContent = key;
        
        // 添加到游戏场景
        const gameScene = document.getElementById('game-scene');
        if (gameScene) {
            gameScene.appendChild(keyEffect);
            
            // 设置初始位置（在小偷上方）
            const thiefElement = document.getElementById('thief-character');
            if (thiefElement) {
                const thiefRect = thiefElement.getBoundingClientRect();
                const sceneRect = gameScene.getBoundingClientRect();
                
                keyEffect.style.left = `${thiefRect.left - sceneRect.left + thiefRect.width / 2}px`;
                keyEffect.style.top = `${thiefRect.top - sceneRect.top - 30}px`;
            }
            
            // 动画结束后移除
            keyEffect.addEventListener('animationend', () => {
                if (keyEffect.parentNode) {
                    keyEffect.parentNode.removeChild(keyEffect);
                }
            });
        }
    }
    
    /**
     * 获取文本完成进度
     * @returns {number} 完成进度 (0-1)
     */
    getProgress() {
        if (this.text.length === 0) return 0;
        return Math.min(1, this.position / this.text.length);
    }
    
    /**
     * 获取当前打字频率（每分钟字符数）
     * @returns {number} 打字频率
     */
    getTypingFrequency() {
        // 如果没有输入，返回0
        if (this.recentInputs.length === 0) {
            return 0;
        }
        
        // 计算最近5秒内的输入数量
        const now = Date.now();
        const timeWindow = 5000; // 5秒
        const recentInputs = this.recentInputs.filter(input => 
            (now - input.timestamp) <= timeWindow && input.isCorrect
        );
        
        // 计算频率（每分钟字符数）
        const frequency = (recentInputs.length / (timeWindow / 60000));
        
        return frequency;
    }
} 